/////////////////////////////////////////////////////////////////
//// Includes ///////////////////////////////////////////////////
#include "SDK30.H"
#include <fm_proto.h>
#include <fm_HMIService.h>
#include "fm_genpinpad.h"
#include "fm_UserInterface.h"

extern void StateHeaders(int st);
#ifdef 		_PASS_GEN_
#include "param.h"
//#include "telium_crypto.h"
#include "crypto_def.h" 
#endif


//// Macros & preprocessor definitions //////////////////////////
#define NUMBER_OF_ITEMS(a)			(sizeof(a)/sizeof((a)[0]))

//// Types //////////////////////////////////////////////////////

//// Global variables ///////////////////////////////////////////

//// Static function definitions ////////////////////////////////
 
//static int HelperDisplayMenuInternal( const char* szTitle, int bRadioButtons, int nDefaultChoice, 
	//								  int nItems, const char* Items[],
		//							  int nBanners );

//// Functions //////////////////////////////////////////////////
#ifdef 		_PASS_GEN_
extern void Des112Decipher  ( T_DES_INPUT *  Input,  
  unsigned char *  Key,  
  unsigned char *  Output   
 ) ;
extern void  Des56Decipher (T_DES_INPUT *Input, unsigned char *Key, unsigned char *Ouput) ;
#endif


#define STATE_INPUT_END				0
#define STATE_INPUT_WAIT_KEY		1
#define STATE_INPUT_KEY_STEP		2

extern int GET_CHAR(void);

#define __GETKEY(tab) \
	if( (tab)[*pnIndex] == '\0' ) *pnIndex = 0; *pcCharacter = (tab)[*pnIndex]; (*pnIndex)++;
	
	const char tKey0[] = { '0', '-', ' ', '\0' };
	const char tKey1[] = { '1', 'q', 'z', 'Q', 'Z', '\0' };
	const char tKey2[] = { '2', 'a', 'b', 'c', 'A', 'B', 'C', '\0' };
	const char tKey3[] = { '3', 'd', 'e', 'f', 'D', 'E', 'F', '\0' };
	const char tKey4[] = { '4', 'g', 'h', 'i', 'G', 'H', 'I', '\0' };
	const char tKey5[] = { '5', 'j', 'k', 'l', 'J', 'K', 'L', '\0' };
	const char tKey6[] = { '6', 'm', 'n', 'o', 'M', 'N', 'O', '\0' };
	const char tKey7[] = { '7', 'p', 'r', 's', 'P', 'R', 'S', '\0' };
	const char tKey8[] = { '8', 't', 'u', 'v', 'T', 'U', 'V', '\0' };
	const char tKey9[] = { '9', 'w', 'x', 'y', 'W', 'X', 'Y', '\0' };
	const char tKeyDot[] = { '.', ',', '\'', ';', ':', '@', '/', '\\', '\0' };

void promptedit(int m,int nKey)
{
	char tmp[10];
	char tmp2[4];
	int i,k;

	memset(tmp,0x00,sizeof(tmp));
	switch( nKey )
	{
	case T_NUM0:memcpy(tmp,tKey0,strlen(tKey0));break;
	case T_NUM1:memcpy(tmp,tKey1,strlen(tKey1));break;
	case T_NUM2:memcpy(tmp,tKey2,strlen(tKey2));break;
	case T_NUM3:memcpy(tmp,tKey3,strlen(tKey3));break;
	case T_NUM4:memcpy(tmp,tKey4,strlen(tKey4));break;
	case T_NUM5:memcpy(tmp,tKey5,strlen(tKey5));break;
	case T_NUM6:memcpy(tmp,tKey6,strlen(tKey6));break;
	case T_NUM7:memcpy(tmp,tKey7,strlen(tKey7));break;
	case T_NUM8:memcpy(tmp,tKey8,strlen(tKey8));break;
	case T_NUM9:memcpy(tmp,tKey9,strlen(tKey9));break;
	case T_POINT:memcpy(tmp,tKeyDot,strlen(tKeyDot));break;
		}
	i=0;
	SetArea(5, 45, 128-10, 60,_OFF_);
	k=StringWidth("0")+2;
	
	while(tmp[i]!=0x00)
	{
	
		tmp2[0]=tmp[i];
		tmp2[1]=0x00;
		
		if (i==m) 
		_DrawString( tmp2, (k*i)+5, 50, _ON_ );	
		else
		_DrawString( tmp2, (k*i)+5, 50, _OFF_ );	
		
		PaintGraphics();
		i++;
	}	
}

static int GetNextCharacter( int nKey, int *pnIndex, char *pcCharacter )
{

	promptedit(*pnIndex,nKey);
	switch( nKey )
	{
	case T_NUM0:__GETKEY(tKey0);break;
	case T_NUM1:__GETKEY(tKey1);break;
	case T_NUM2:__GETKEY(tKey2);break;
	case T_NUM3:__GETKEY(tKey3);break;
	case T_NUM4:__GETKEY(tKey4);break;
	case T_NUM5:__GETKEY(tKey5);break;
	case T_NUM6:__GETKEY(tKey6);break;
	case T_NUM7:__GETKEY(tKey7);break;
	case T_NUM8:__GETKEY(tKey8);break;
	case T_NUM9:__GETKEY(tKey9);break;
	case T_POINT:__GETKEY(tKeyDot);break;

	case T_APAP:
	case T_VAL:
	case T_ANN:
	case T_CORR:
	case T_SK1:
	case T_SK2:
	case T_SK3:
	case T_SK4:
	case T_SKHAUT:
	case T_SKBAS:
	case T_SKVAL:
	case T_SKCLEAR:
	case T_SK10:
	default:
		return '\0';
	}


	
	return 1;
}


uint8 crdUnpackTrack2(uint8 *dest, uint8 *src)
{
	uint8 count;

	for(count=0;;)
	{
		dest[count++] = ((*src & 0xf0) >> 4) | 0x30;
		if (count > 36)
			break;

		dest[count++] = (*src++ & 0x0f) | 0x30;
	}

	return(count);
}

void ClearText( char *szInput, int xInput, int yInput )
{
	int nWidth;

	// Erase all text
	nWidth =  StringWidth( szInput ) + 4;

	_SetArea( xInput, yInput, xInput + nWidth, yInput + _SIZE_MEDIUM_, _OFF_ );
}


static int EraseCharacterInText( char *szInput, int xInput, int yInput, int nIndex  )
{
	int i = 0;
	int len = strlen( szInput );

	// Clear current text.
	ClearText( szInput, xInput, yInput );

	//
	for( i = nIndex; i < len; i++ )
	{
		szInput[i] = szInput[i+1];
	}

	szInput[i] = '\0';

	if(( nIndex >= len - 1 ) && ( nIndex != 0 ))
	{
		nIndex--;
	}

	DisplayText( szInput, xInput, yInput, nIndex, 0  );

	return nIndex;
}



void DisplayText( char *szInput, int x, int y, int index, int bErase  )
{
	// Display the string
	char tc[2];

	int xCursor, yCursor;

	int i = 0;
	int len = strlen( szInput );

	tc[1] = '\0';

	if( bErase == 1 )
	{
		ClearText( szInput, x, y );
	}

	xCursor = x;
	yCursor = y + _SIZE_MEDIUM_;

	for( i = 0; i < len; i++ )
	{
		tc[0] = szInput[i];
		if( i == index )
		{

			xCursor = x;
		}

		DrawString( tc, x, y, _OFF_ );

		x += StringWidth( tc );
	}

	if( index >= len )
	{
		xCursor = x;
	}

	if( index != -1 )
	{
		DrawLine( xCursor, yCursor, xCursor + 4, yCursor, _ON_ );
	}

	PaintGraphics();
}

static int SetCharacterInText( char *szInput, int xInput, int yInput,
							   int nIndex, char Character, int nMax )
{
	if( nIndex == nMax )
	{	
		return 0;
	}

	// Clear current text.
	ClearText( szInput, xInput, yInput );


	if( szInput[nIndex] == '\0' )
	{
		szInput[nIndex] = Character;
		szInput[nIndex+1] = '\0';
	}
	else
	{
		szInput[nIndex] = Character;
	}

	
	DisplayText( szInput, xInput, yInput, nIndex, 0  );
	
	return 1;
}


//int HelperManageInput( char *szLabel, int xLabel, int yLabel,
//					   char *szInput, int xInput, int yInput, 
//					   int nMaxLen, int bNumerical, int nTimeout )
int HelperManageInput( char *szInput, int xInputs, int yInputs, int nMinLen,
					   int nMaxLen, int bNumerical, int nTimeout )
{

	int nResult	= 0;

	int nKey1		= 0;
	int nKey2		= 0;
	int nKeyIndex	= 0;
	char Character	= '\0';
	int xInput, yInput;
	int n;
	int nState;

	n = 0;
	nResult = 1;
	nState = STATE_INPUT_WAIT_KEY;



	n = strlen( szInput );
	yInput= (10*(xInputs-1))+15;
	xInput=((yInputs)*StringWidth("S"))+3;
	
	DisplayText( szInput, xInput, yInput, n, 0 );

	while( nState !=  STATE_INPUT_END )
	{
		switch( nState )
		{
			case STATE_INPUT_WAIT_KEY:
			{
				// Wait a key
				if( ttestall(KEYBOARD, nTimeout ) == KEYBOARD ) 
				{
					nKey1 = GET_CHAR();

					// Monitor key Step.
					switch( nKey1 )
					{
					case T_CORR:
						// Arrow keys.
						n = EraseCharacterInText( szInput, xInput, yInput, n );
						break;

					case T_SK1: // Left
						// Arrow keys.
						if( n != 0 )
						{
							n--;
							DisplayText( szInput, xInput, yInput, n, 1 );
						}
						break;

					case T_SK4: // Right
						// Arrow keys.
						if( szInput[n] != '\0' )
						{
							n++;
						}
						DisplayText( szInput, xInput, yInput, n, 1 );
						break;

					case T_VAL: 
											
						nResult = __ENTER_KEY;
						nState =  STATE_INPUT_END;
						break;

					case T_SK2: // Back
						nResult = __BACK_KEY;
						nState =  STATE_INPUT_END;
						break;

					case T_ANN:
						nResult = nMinLen;
						nState =  STATE_INPUT_END;					
						break;

					case T_NUM0:
					case T_NUM1:
					case T_NUM2:
					case T_NUM3:
					case T_NUM4:
					case T_NUM5:
					case T_NUM6:
					case T_NUM7:
					case T_NUM8:
					case T_NUM9:
					case T_POINT:						
						nState = STATE_INPUT_KEY_STEP;
						nKeyIndex = 0;

						if( GetNextCharacter( nKey1, &nKeyIndex, &Character ) != 0 )
						{
							SetCharacterInText( szInput, xInput, yInput, n, Character, nMaxLen );
						}
						break;
					}
				}
				else
				{
						nState = STATE_INPUT_END;
						nResult = 0; // Timeout;
				}
			}
			break;

			

			case STATE_INPUT_KEY_STEP:
			{
				// Monitor key Step.
				Character = nKey1;

				if(( bNumerical == 0) &&  ( ttestall(KEYBOARD, 100 ) == KEYBOARD )) 
				{
					nKey2 = getchar();

					if ( nKey1 != nKey2 ) 
					{
						nKey1 = nKey2;
						Character = nKey1;
						n++;

						switch( nKey1 )
						{
						case T_CORR:
							// Arrow keys.
							n = EraseCharacterInText( szInput, xInput, yInput, n );
							nState = STATE_INPUT_WAIT_KEY;
							break;

						case T_SK1: // Left
							// Arrow keys.
							if( n != 0 )
							{
								n--;
								DisplayText( szInput, xInput, yInput, n, 1 );
							}
							nState = STATE_INPUT_WAIT_KEY;
							break;

						case T_SK4: // Right
							// Arrow keys.
							if( szInput[n] != '\0' )
							{
								n++;
								DisplayText( szInput, xInput, yInput, n, 1 );
							}
							nState = STATE_INPUT_WAIT_KEY;
							break;

						case T_VAL: 
					
							nResult = __ENTER_KEY;
							nState =  STATE_INPUT_END;
							break;

						case T_SK2: // Back
							nResult = __BACK_KEY;
							nState =  STATE_INPUT_END;
							break;


						case T_ANN:
							nResult = __EXIT_KEY;
							nState =  STATE_INPUT_END;					
							break;

						case T_NUM0:
						case T_NUM1:
						case T_NUM2:
						case T_NUM3:
						case T_NUM4:
						case T_NUM5:
						case T_NUM6:
						case T_NUM7:
						case T_NUM8:
						case T_NUM9:
						case T_POINT:
							nKeyIndex = 0;
							SetCharacterInText( szInput, xInput, yInput, n, Character, nMaxLen );
							promptedit(nKeyIndex,nKey1);
							DisplayText( szInput, xInput, yInput, n, 1 );
							break;
						}
					}
					else
					{
						// Rotate on the same key.
						if( GetNextCharacter( nKey1, &nKeyIndex, &Character ) != 0 )
						{
							if( SetCharacterInText( szInput, xInput, yInput, n, Character, nMaxLen ) == 1 )
							{
							}
						}
						else
						{
							// ??
						}
					}
				}
				else
				{
					if( nKeyIndex == 0 )
					{
						SetCharacterInText( szInput, xInput, yInput, n, Character, nMaxLen );
					}

					n++;
					DisplayText( szInput, xInput, yInput, n, 1 );
					nState = STATE_INPUT_WAIT_KEY;
				}
			}
			break;
		}
		if (nState ==  STATE_INPUT_END)
			if ((nResult == __ENTER_KEY) && (strlen(szInput)<nMinLen))
				{
					nState=STATE_INPUT_WAIT_KEY;
				}
	}

	return nResult;
}



static int HelperDisplayMenuInternal(const char* szTitle, int bRadioButtons, int nDefaultChoice, int nItems, const char* Items[], int nBanners )
{
	int nSizeX;
	int nSizeY;
	StructList Menu;
	int i;
	
	int nInput;
	int nReturn;

	int nBannerHeight = 0;


	ENTRY_BUFFER Entry;

	if ((nDefaultChoice < 0) || (nDefaultChoice >= nItems))
		nDefaultChoice = 0;

	GetScreenSize(&nSizeY, &nSizeX);

	CreateGraphics(_MEDIUM_);

	switch( nBanners )
	{
	case __ONE_BANNER:
		nBannerHeight = 12;
		break;

	case __ALL_BANNERS:
		nBannerHeight = 19;
		break;

	case __NO_BANNER:
	default:
		nBannerHeight = 0;
		break;
	}

	memset(&Menu, 0, sizeof(Menu));
	Menu.MyWindow.left = 0;
	Menu.MyWindow.top = nBannerHeight;
	Menu.MyWindow.rigth = nSizeX - 1;
	Menu.MyWindow.bottom = nSizeY - 1;
	if (nSizeY == 128)
	{
		Menu.MyWindow.nblines = 10;
	}
	else
	{
		Menu.MyWindow.nblines = 5;
	}

	Menu.MyWindow.fontsize = _MEDIUM_;
	Menu.MyWindow.type = _PROPORTIONNEL_;
	Menu.MyWindow.font = 0;
	Menu.MyWindow.correct = _ON_;
	Menu.MyWindow.offset = 0;
	Menu.MyWindow.shortcommand = _ON_;
	if (bRadioButtons)
		Menu.MyWindow.selected = _ON_;
	else Menu.MyWindow.selected = _OFF_;
	Menu.MyWindow.thickness = 2;
	Menu.MyWindow.border = _ON_;
	Menu.MyWindow.popup = _NOPOPUP_;
	Menu.MyWindow.first = nDefaultChoice;
	Menu.MyWindow.current = nDefaultChoice;
	Menu.MyWindow.time_out = 60;
	Menu.MyWindow.title = (unsigned char*)szTitle;

	for(i = 0; i < nItems; i++)
		Menu.tab[i] = (unsigned char*)Items[i];

	G_List_Entry((void*)&Menu);
	ttestall(ENTRY, 0);
	nInput = Get_Entry((void*)&Entry);

	switch( nInput )
	{
	case CR_ENTRY_OK:
		nReturn = Entry.d_entry[0];
		break;

	case CR_ENTRY_NOK:
		nReturn = __EXIT_KEY;
		break;

	default:
		nReturn = __BACK_KEY;
		break;
	}

	return nReturn;
}

int HelperDisplayMenu( const char* szTitle, int nDefaultChoice,
					   int nItems, const char* Items[],
					   int nBanners )
{
	return HelperDisplayMenuInternal( szTitle, FALSE, nDefaultChoice, 
									  nItems, Items, nBanners );
}

int HelperDisplayChoices( const char* szTitle, int nDefaultChoice,
						  int nItems, const char* Items[],
					      int nBanners )

{
	return HelperDisplayMenuInternal( szTitle, TRUE, nDefaultChoice, 
									  nItems, Items,
									  nBanners );
}

int HelperNumericInput(const char* szTitle, const char* szLabel, int nMinLength, int nMaxLength, const char* szDefault, char* szInput)
{
	int nSizeX;
	int nSizeY;
	StructList Input;
	int nInput;
	int nReturn;

	TAB_ENTRY_STRING EntryNumeric;
	ENTRY_BUFFER Entry;

	if (nMaxLength >= 20)
		nMaxLength = 20;
	if (nMinLength > nMaxLength)
		nMinLength = nMaxLength;

	GetScreenSize(&nSizeY, &nSizeX);

	memset(&Input, 0, sizeof(Input));
	Input.MyWindow.left = 0;
	Input.MyWindow.top = 0;
	Input.MyWindow.rigth = nSizeX - 1;
	Input.MyWindow.bottom = nSizeY - 1;
	if (nSizeY == 128)
		Input.MyWindow.nblines = 10;
	else Input.MyWindow.nblines = 5;
	Input.MyWindow.fontsize = _MEDIUM_;
	Input.MyWindow.type = _PROPORTIONNEL_;
	Input.MyWindow.font = 0;
	Input.MyWindow.correct = _ON_;
	Input.MyWindow.offset = 0;
	Input.MyWindow.shortcommand = _ON_;
	Input.MyWindow.selected = _OFF_;
	Input.MyWindow.thickness = 2;
	Input.MyWindow.border = _ON_;
	Input.MyWindow.popup = _NOPOPUP_;
	Input.MyWindow.first = 0;
	Input.MyWindow.current = 0;
	Input.MyWindow.time_out = 120;
	Input.MyWindow.title = (unsigned char*)szTitle;

	Input.tab[0] = (unsigned char*)szLabel;
	Input.tab[1] = (unsigned char*)szDefault;

	EntryNumeric.mask = 0;
	EntryNumeric.time_out = 120;
	EntryNumeric.line = 32;
	if (nMaxLength <= 18)
		EntryNumeric.column = 10;
	else if (nMaxLength == 19)
		EntryNumeric.column = 6;
	else EntryNumeric.column = 4;
	EntryNumeric.echo = ECHO_NORMAL;
	EntryNumeric.nb_max = nMaxLength;
	EntryNumeric.nb_min = nMinLength;

	G_Numerical_Entry((void*)&Input, (void*)&EntryNumeric);
	ttestall(ENTRY, 0);
	nInput = Get_Entry((void*)&Entry);

	szInput[0] = '\0';

	switch( nInput )
	{
	case  CR_ENTRY_OK:
		strncpy(szInput, (char*)Entry.d_entry, Entry.d_len);
		szInput[Entry.d_len] = '\0';
		nReturn = __ENTER_KEY;
		break;

	case CR_ENTRY_VALIDATED:
		strcpy(szInput, szDefault);
		nReturn = __ENTER_KEY;
		break;

	case CR_ENTRY_NOK:
		nReturn = __BACK_KEY;
		break;

	default:
		nReturn = __EXIT_KEY;
		break;
	}

	return nReturn;
}


#ifdef 		_PASS_GEN_
char* pinfunction(char *pin, char *pout)
{
	#define KEY1 (unsigned char*)"1478290683597685"
	
	T_DES_INPUT inp;	
	unsigned char buftmp2[16];
	unsigned char tmpout[16];
	int i;

	memset(tmpout, 0x00, sizeof(tmpout));	
	memcpy(buftmp2, pin,8);
	inp.InputLen=8;
	inp.Input=buftmp2;
	Des112Decipher(&inp,KEY1, tmpout);
		
	Hexasc((unsigned char*)pout, tmpout, 8)	;
	//xx_hex_dump(0, "after", pout, 8);
	for ( i=0;i<8;i++)
	{
		if (pout[i]>'9')
			pout[i]=pout[i]-0x0A;
	}
	//xx_hex_dump(0, "after2", pout, 8);	
	return pout;
}
char* getrand(char* buf)
{
#define KEY_PIN (unsigned char*)"90683597"

	unsigned char tmp[16];
	unsigned char tmp2[10];
	T_DES_INPUT inp;	
	int i;
	DATE date_buffer;		
	
  	if (read_date(&date_buffer)!=0)
		return NULL;

	memset(tmp, 0x00, sizeof(tmp));
	memcpy(tmp, &date_buffer, 12);
	memset(tmp2, 0x00, sizeof(tmp2));
	Aschex(tmp2, tmp, 12);
	tmp2[6]=0x11;
	tmp2[7]=0x22;
	
	memset(tmp,0x00, sizeof(tmp));
	inp.InputLen=8;
	inp.Input=tmp2;	
	Des56Decipher(&inp, KEY_PIN,tmp);

	memset(buf, 0x00, 5);
	Hexasc((unsigned char*)buf, tmp, 4)	;
	//xx_hex_dump(0, "after", pout, 8);
	for ( i=0;i<4;i++)
	{
		if (buf[i]>'9')
			buf[i]=buf[i]-0x0A;
	}
	
	return buf;
}
#endif

void displaystar(int line, int col,int len)
{
	char buff[30];

	memset(buff,'*',sizeof(buff));	
	buff[len]=0x00;
	pp_display_text(line, col, buff, PT_ALIGN_LEFT|PT_CLEAR);
}

#ifdef 		_PASS_GEN_
int PasswordEntry(char *pwd,int line, int col,int nMinLen,
					   int nMaxLen, int instar, int nTimeout )
{
	int nResult,nkey;
	uint16 t;
	char buff[30];
	nResult=0;
	memset(buff,0x00,sizeof(buff));
	if (pwd[0]!=0)
	{
		strcpy(buff, pwd);
		nResult=strlen(pwd);
		pp_display_text(line, col, buff, PT_ALIGN_LEFT|PT_CLEAR);		
	}
	
	while(TRUE)
	{
		t=ttestall(KEYBOARD, nTimeout * 100);
		if( t == KEYBOARD ) 
		{
				
		nkey=GET_CHAR();
		switch(nkey)
		{

			case T_CORR:		
			case VK_CLEAR:	
			
					if (nResult>0)					
						nResult--;

					memset(&buff[nResult],0x00,sizeof(buff)-nResult);
					break;
			case T_VAL: 
			case VK_ENTER: 
					
					if (nResult>=nMinLen)
					{
						strcpy(pwd,buff);						
						return nResult;
					}
					
					break;
				case T_ANN:
				case VK_CANCEL:
					return 0;
					break;

				case T_NUM0:
				case T_NUM1:
				case T_NUM2:
				case T_NUM3:
				case T_NUM4:
				case T_NUM5:
				case T_NUM6:
				case T_NUM7:
				case T_NUM8:
				case T_NUM9:
					if (nResult<nMaxLen)
					{
						buff[nResult]=nkey;
						nResult++;
						
					}
					break;
		}

		if (instar)
			displaystar(line,col,nResult);
		else
			pp_display_text(line, col, buff, PT_ALIGN_LEFT|PT_CLEAR);
		
	}
	else if (t==TIMEOUT_T)// choice For Y/N 
		{

                  pp_beep(5);
		    pp_display_text(4,1,"TIMEO UT ",PT_ALIGN_RIGHT|PT_CLEAR);			   
		    pp_display_text(5,1,"Y/N ",PT_ALIGN_RIGHT|PT_CLEAR);			   	
		    if ((VK_ENTER== GET_CHAR())||(T_VAL==GET_CHAR()))
		   	continue;
		   else
		   return 0;
		  
		}
		
		
	}

	return nResult;
}


int GetSecurityKey(void)
{
	S_EQUIPEMENT Equipment;
	char tmpbuf1[20];
	char tmpbuf2[20];
	char serno[20+1];
	char pary[16];
	char pwdBuf[16];			
	

	pp_display_clear(0);

	memset(&Equipment, 0x00, sizeof (S_EQUIPEMENT));
	PSQ_Donner_reference(&Equipment);

	memset(serno, 0, sizeof(serno));
	memcpy(serno, Equipment.no_serie, 8);			
	sprintf(tmpbuf1,"S/N=%s", serno);			
	pp_display_text(2, 0, tmpbuf1, PT_ALIGN_LEFT | PT_CLEAR);	
				
	memset(pary, 0, sizeof(pary));
	getrand(pary);
	
	strcpy(tmpbuf2, pary);
	memcpy(&pary[4], tmpbuf2, 4);
	pary[8]=0x00;
	sprintf(tmpbuf1,"PIN PARAM=%s", tmpbuf2);
	pp_display_text(1, 0, tmpbuf1, PT_ALIGN_LEFT | PT_CLEAR);			
	pp_display_text(3, 0, "SECURITY CODE ?", PT_ALIGN_LEFT | PT_CLEAR);			
			
	
	memset(pwdBuf, 0, sizeof(pwdBuf));
	if(PasswordEntry(pwdBuf,4, 10, 8, 8, TRUE, 30)==0)
		return STOP;
	else
	{
			int k;
		
			memset(tmpbuf1, 0x00, sizeof(tmpbuf1));
			for (k=0;k<8;k++)
				tmpbuf1[k]=serno[k]^pary[k];					
			
			memset(tmpbuf2, 0x00, sizeof(tmpbuf2));	
			pinfunction(tmpbuf1, tmpbuf2);		
			
			if(memcmp(pwdBuf, tmpbuf2, 8)!=0)
			{
				pp_beep(3);
				pp_display_text(3, 0, "INVALID CODE", PT_ALIGN_CENTER | PT_CLEAR);
				return STOP;	
			}
	}
	return FCT_OK;	
}


#else

int PasswordEntry(char *pwd,int line, int col,int nMinLen,
					   int nMaxLen, int instar, int nTimeout )
{
	int nResult,nkey;
	uint16 t;
	char buff[30];
	nResult=0;
	memset(buff,0x00,sizeof(buff));
	if (pwd[0]!=0)
	{
		strcpy(buff, pwd);
		nResult=strlen(pwd);
		pp_display_text(line, col, buff, PT_ALIGN_LEFT|PT_CLEAR);		
	}
	
	while(TRUE)
	{
		t=ttestall(KEYBOARD, nTimeout * 100);
		if( t == KEYBOARD ) 
		{
				
		nkey=GET_CHAR();
		switch(nkey)
		{
			case T_CORR:					
					if (nResult>0)					
						nResult--;

					memset(&buff[nResult],0x00,sizeof(buff)-nResult);
					break;
				
				case T_VAL: 
					if (nResult>=nMinLen)
					{
						strcpy(pwd,buff);
						return nResult;
					}
					
					break;

				case T_ANN:
					return 0;
					break;

				case T_NUM0:
				case T_NUM1:
				case T_NUM2:
				case T_NUM3:
				case T_NUM4:
				case T_NUM5:
				case T_NUM6:
				case T_NUM7:
				case T_NUM8:
				case T_NUM9:
					if (nResult<nMaxLen)
					{
						buff[nResult]=nkey;
						nResult++;
						
					}
					break;
		}

		if (instar)
			displaystar(line,col,nResult);
		else
			pp_display_text(line, col, buff, PT_ALIGN_LEFT|PT_CLEAR);
		
	}
	else if (t==TIMEOUT_T)
		return 0;
		
	}

	return nResult;
}
#endif
// sorry guys, im in Lazyyyyyyy
int PasswordEntryTime(unsigned char * ucTrack2, int lenpan ,char *pwd,int line, int col,int nMinLen,
					   int nMaxLen, int instar, int nTimeout )
{
	int nResult,nkey;
	uint16 t;
	char buff[30];
      //  char szcpan[21];
		//uint8 PANLength=0
		//		uint8 PANLength, track2[41], PANs[16];
	uint8  PANs[16];

	//PANLength = (uint8)crdGetPANLength(ucTrack2);
//	crdUnpackTrack2(track2, ucTrack2);

//	memset(PANs, 0x00, sizeof PANs);
	
	memcpy(PANs, ucTrack2,lenpan);
//	PANs[PANLength] = 0;	
	
	nResult=0;
	memset(buff,0x00,sizeof(buff));
	
	StateHeaders(0);
  	pp_display_clear(0);
	 pp_settittle("PINPAD");
	pp_display_text(2, 0, PANs, PT_ALIGN_LEFT|PT_CLEAR);
  	pp_display_text(3, 0, "PIN", PT_ALIGN_LEFT|PT_CLEAR);
	if (pwd[0]!=0)
	{
		strcpy(buff, pwd);
		nResult=strlen(pwd);
		pp_display_text(line, col, buff, PT_ALIGN_LEFT|PT_CLEAR);
	}

	while(TRUE)
	{
		t=ttestall(KEYBOARD, nTimeout * 100);
		_trace("event %d",t);
		if( t == KEYBOARD )
		{

		nkey=GET_CHAR();
		switch(nkey)
		{
			case T_CORR:
					if (nResult>0)
						nResult--;

					memset(&buff[nResult],0x00,sizeof(buff)-nResult);
					break;

				case T_VAL:
					if (nResult>=nMinLen)
					{
						strcpy(pwd,buff);
						return nResult;
					}

					break;

				case T_ANN:
					return 0;
					break;

				case T_NUM0:
				case T_NUM1:
				case T_NUM2:
				case T_NUM3:
				case T_NUM4:
				case T_NUM5:
				case T_NUM6:
				case T_NUM7:
				case T_NUM8:
				case T_NUM9:
					if (nResult<nMaxLen)
					{
						buff[nResult]=nkey;
						nResult++;

					}
					if (nResult>=nMaxLen)
						{ 
						   pp_beep(1);
						   
						}
					
					break;
		}

		if (instar)
			displaystar(line,col,nResult);
		else
			pp_display_text(line, col, buff, PT_ALIGN_LEFT|PT_CLEAR);

	}
	else if (t==0)
		return -1;

	}

	return nResult;
}
void displaytxt(char *bufstr, int line, int maxlen, int typedat)
{
	char buftmp[32+1];
	char buftmp2[32+1];
	char buf[32+1];
	int len,k;

	//memset(buf, 0x00, sizeof (buf));
	//if (bufstr[0]);
	strcpy(buf, bufstr);
	
	len=strlen(buf);	
	if (typedat==FMSTAR)
	{
		memset(buf,'*',len);
		buf[len]=0x00;
	}
		
	memset(buftmp2, 0x00, sizeof(buftmp2));
	buftmp2[0]='[';
	if (maxlen>19)
		maxlen=19;
	
	
	if (len>maxlen)
	{
		k=len-maxlen;		
		memcpy(&buftmp2[1], &buf[k],maxlen);
		
	}
	else
	{
		k=maxlen-len;
		memset(buftmp,' ',maxlen);			
		memcpy(&buftmp[k], buf,len);
		memcpy(&buftmp2[1],buftmp,maxlen);
	}	
	buftmp2[maxlen+1]=']';
	
	pp_display_text(line, 0, buftmp2, PT_ALIGN_CENTER|PT_CLEAR);
}

char getcharalp(int nKey, int *idx)
{
	char tmp[10];
	int len;
	memset(tmp,0x00,sizeof(tmp));
		
	switch( nKey )
		{
		case T_NUM0:memcpy(tmp,tKey0,strlen(tKey0));break;
		case T_NUM1:memcpy(tmp,tKey1,strlen(tKey1));break;
		case T_NUM2:memcpy(tmp,tKey2,strlen(tKey2));break;
		case T_NUM3:memcpy(tmp,tKey3,strlen(tKey3));break;
		case T_NUM4:memcpy(tmp,tKey4,strlen(tKey4));break;
		case T_NUM5:memcpy(tmp,tKey5,strlen(tKey5));break;
		case T_NUM6:memcpy(tmp,tKey6,strlen(tKey6));break;
		case T_NUM7:memcpy(tmp,tKey7,strlen(tKey7));break;
		case T_NUM8:memcpy(tmp,tKey8,strlen(tKey8));break;
		case T_NUM9:memcpy(tmp,tKey9,strlen(tKey9));break;
		case T_POINT:memcpy(tmp,tKeyDot,strlen(tKeyDot));break;
		}

	len=strlen(tmp)-1;
	if (*idx>len)
		*idx=0;
	if (*idx<0)
		*idx=len;

	return tmp[(*idx)];
}

int getidxstr(char inp)
{
	int i,nkey,len;
	char tmp[10];
	
	nkey=T_NUM0;
	do
	{
		if (nkey>T_NUM9)
			nkey=T_POINT;
		
		switch( nkey )
		{
			case T_NUM0:memcpy(tmp,tKey0,strlen(tKey0));break;
			case T_NUM1:memcpy(tmp,tKey1,strlen(tKey1));break;
			case T_NUM2:memcpy(tmp,tKey2,strlen(tKey2));break;
			case T_NUM3:memcpy(tmp,tKey3,strlen(tKey3));break;
			case T_NUM4:memcpy(tmp,tKey4,strlen(tKey4));break;
			case T_NUM5:memcpy(tmp,tKey5,strlen(tKey5));break;
			case T_NUM6:memcpy(tmp,tKey6,strlen(tKey6));break;
			case T_NUM7:memcpy(tmp,tKey7,strlen(tKey7));break;
			case T_NUM8:memcpy(tmp,tKey8,strlen(tKey8));break;
			case T_NUM9:memcpy(tmp,tKey9,strlen(tKey9));break;
			case T_POINT:memcpy(tmp,tKeyDot,strlen(tKeyDot));break;
		}
		
		len=strlen(tmp);
		for (i=0; i<len;i++)
		{
			if (inp==tmp[i])
				return nkey;
		}
		
		nkey++;
	}while(nkey!=T_POINT);

	return 0;
}

int HelperManageInputFM( char *szInput, int xInputs, int nMinLen,
					   int nMaxLen, int typedat, int nTimeout )
{
	int nResult=0;
	int nkey;
	uint16 t;
	char buff[30];
	int idx=0;
	int len;
	int nixdkey=-1;
	
	memset(buff,0x00,sizeof(buff));
	len=strlen(szInput);
	if (len)
	{
		strcpy(buff, szInput);
		nResult=len;
		nixdkey=getidxstr(szInput[len-1]);
	}

	displaytxt(szInput, xInputs,  nMaxLen, typedat);
	
	while(TRUE)
	{
		t=ttestall(KEYBOARD, nTimeout * 100);
		if( t == KEYBOARD ) 
		{
				
		nkey=GET_CHAR();
		switch(nkey)
		{
			case T_CORR:					
					if (nResult>0)					
						nResult--;

					memset(&buff[nResult],0x00,sizeof(buff)-nResult);
					break;
				
				case T_VAL: 
					if (nResult>=nMinLen)
					{
						strcpy(szInput,buff);
						return __ENTER_KEY;
					}
					
					break;

				case T_ANN:
					return __EXIT_KEY;
					break;

				case DOWN:					
					idx--;
					if ((typedat==FMALPHANUM) && (nixdkey>-1))
						buff[nResult-1]=getcharalp(nixdkey,&idx);
					break;
				case UP:
					idx++;
					if ((typedat==FMALPHANUM) && (nixdkey>-1))
						buff[nResult-1]=getcharalp(nixdkey,&idx);
					break;
				
				case T_NUM0:
				case T_NUM1:
				case T_NUM2:
				case T_NUM3:
				case T_NUM4:
				case T_NUM5:
				case T_NUM6:
				case T_NUM7:
				case T_NUM8:
				case T_NUM9:
				case T_POINT:
					if ((nkey==T_POINT) && (typedat!=FMALPHANUM))
						break;

					if (nResult<nMaxLen)
					{
						nixdkey=(int)nkey;
						idx=0;
						buff[nResult]=nkey;
						nResult++;
						
					}
					break;
					
		}

		
		displaytxt(buff, xInputs,  nMaxLen, typedat);
	}
	else if (t==TIMEOUT_T)
		return 0;
		
	}

	return nResult;
}

